package main

import "fmt"

/**
func printArray(arr [5]int)
func printArray(arr []int)
- [5]int是表示一个数组，数组是值类型的
- []int是表示一个切片
- arr这个入参，函数被调用的时候，是做了一个内存里面的值的一个拷贝，里面的arr不影响外边的arr
*/
func printArray(arr [5]int) {
	// 希望不仅仅获得数组的下标，我还想获取到数组的值可不可以，答案是可以的
	for i, v := range arr {
		fmt.Println(fmt.Sprintf("我是par，下标%d=》值为%d", i, v))
	}
}

func printArray2(arr *[5]int) {
	// 我想改变第0号元素咋改
	// 第一种写法：
	//(*arr)[0] = 100
	// 一般是第二种写法，go语言直接把*去掉
	arr[0] = 100

	// 希望不仅仅获得数组的下标，我还想获取到数组的值可不可以，答案是可以的
	for i, v := range arr {
		fmt.Println(fmt.Sprintf("我是par，下标%d=》值为%d", i, v))
	}
}

func main() {
	var arr [5]int
	arr1 := [3]int{1, 2, 3}
	arr2 := [...]int{1, 2, 2, 8, 10}
	fmt.Println(arr, arr1, arr2)

	// 定义多维数组，比如4行5列，里边bool的零值false，如果是int的零值是0
	var grid [4][5]bool
	fmt.Println(grid)

	// 遍历数组的方法
	//for i := 0; i < len(arr2); i++ {
	//	fmt.Println(arr2[i])
	//}

	// 更推荐的遍历数组的方式，使用range这个关键字可以获取数组的一个par
	//for i := range arr2 {
	//	fmt.Println(arr2[i])
	//}

	// 希望不仅仅获得数组的下标，我还想获取到数组的值可不可以，答案是可以的
	//for i, v := range arr2 {
	//	fmt.Println(fmt.Sprintf("我是par，下标%d=》值为%d", i, v))
	//}

	// 希望只获取值，不想要下标
	//for _, v := range arr2 {
	//	fmt.Println(v)
	//}

	printArray(arr)
	printArray(arr2)
	// printArray(arr1) // cannot use arr1 (type [3]int) as type [5]int in argument to printArray
	/**
	- 在go语言中，type [3]int 和type [5]int 被认为不是相同的数据类型，所以长度不相同传不进去
	*/
	printArray2(&arr2) //&表示取变量的地址

}

/**
数组的遍历range关键字
- 可以通过_来省略变量
- 不仅range，任何地方都可以通过_省略接收变量
- 如果只需要的是par的下标，可写成 for i := range numbers

为什么要使用range？
- 意义明确，美观
- C++没有类似能力，不过它的库有
- Java/Python：只能for each value，不能同时获取i，v，不过他们的库有
- Javascript有个类似的for..in

数组为什么是值类型？
- 值类型就是拷贝
- 因为数组是值类型，所以我们必须规定数组的一个长度
- [10]int和[20]int是不同类型
- 调用func f(arr [10]int) 会 【拷贝】 整个数组
- 之前说过go语言参数传递只有一种方式，就是值传递，那么值传递就会走拷贝
- go语言不像其他一些语言一样就不支持传引用，但是可以用指针来实现引用的效果
- 实现类似传引用的效果，比如只想这个数组的指针可以吗，当然这个是可以的
- 数组麻烦的地方就是必须要定义一下长度，所以对go语言来说，在go语言中一般不直接使用数组，这样麻烦不符合go的意图，一般正常开发都是使用的是go语言的切片
*/
